using System;
using System.Collections.Generic;
using System.Text;
using System.Data;
using System.Data.SqlClient;
using Deepcode.Flux.Core.Data;

namespace Deepcode.Flux.Core.Systems.Scheduler
{
	/// <summary>
	/// Manager class for the scheduled task records
	/// </summary>
	public class Tasks : BaseManager
	{
		#region Constructors
		public Tasks() : base() { }
		public Tasks(SqlConnection CurrentConnection) : base(CurrentConnection) { }
		public Tasks(SqlConnection CurrentConnection, SqlTransaction CurrentTransaction) : base(CurrentConnection, CurrentTransaction) { }
		#endregion
		/// <summary>
		/// Retrieves all tasks in taskname order
		/// </summary>
		/// <returns></returns>
		public Task[] GetAllTasks()
		{
			return GetAllTasks(TaskSortOrder.TaskName);
		}
		/// <summary>
		/// Retrieves all tasks sorted by the order specified (ascending order)
		/// </summary>
		/// <param name="order"></param>
		/// <returns></returns>
		public Task[] GetAllTasks(TaskSortOrder order)
		{
			return GetAllTasks(order, DataSortDirection.ASCENDING);
		}
		/// <summary>
		/// Retrieves all tasks sorted by the sort order specified, with
		/// the sort direction specified.
		/// </summary>
		/// <param name="order"></param>
		/// <param name="direction"></param>
		/// <returns></returns>
		public Task[] GetAllTasks(TaskSortOrder order, DataSortDirection direction)
		{
			DataTable results = new DataTable();
			EstablishConnection();
			SqlDataAdapter da = this.CreateDataAdapter("coreSchedulerGetAll");
			da.SelectCommand.Parameters.Add(SQLUtility.ParameterIn("@OrderBy", SqlDbType.Int, 4, (int) order));
			da.SelectCommand.Parameters.Add(SQLUtility.ParameterIn("@SortDirection", SqlDbType.Int, 4, (int)direction));
			da.Fill(results);
			ReleaseConnection();

			List<Task> list = new List<Task>();
			foreach (DataRow r in results.Rows)
				list.Add(new Task(r));

			return list.ToArray();
		}
		/// <summary>
		/// Gets all of the tasks that are presently due
		/// </summary>
		/// <returns></returns>
		public Task[] GetDueTasks()
		{
			DataTable results = new DataTable();
			EstablishConnection();
			SqlDataAdapter da = this.CreateDataAdapter("coreSchedulerGetAllDue");
			da.Fill(results);
			ReleaseConnection();

			List<Task> list = new List<Task>();
			foreach (DataRow r in results.Rows)
				list.Add(new Task(r));

			return list.ToArray();
		}
		/// <summary>
		/// Finds and returns a task by it's unique ID
		/// </summary>
		/// <param name="ID"></param>
		/// <returns></returns>
		public Task GetTaskByID(int ID)
		{
			DataTable result = new DataTable();

			EstablishConnection();
			SqlDataAdapter da = this.CreateDataAdapter("coreSchedulerGetByID");
			da.SelectCommand.Parameters.Add(SQLUtility.ParameterIn("@PK_ID", SqlDbType.Int, 4, ID));
			da.Fill(result);
			ReleaseConnection();

			if (result == null) return null;
			if (result.Rows.Count < 1) return null;

			return new Task(result.Rows[0]);
		}
		/// <summary>
		/// Saves the specified task to the database.
		/// </summary>
		/// <param name="User"></param>
		/// <returns></returns>
		public int Save(Task task)
		{
			EstablishConnection();
			SqlCommand cmd = this.CreateSqlCommand("coreSchedulerSave");
			SqlParameter result = SQLUtility.ParameterInOut("@PK_ID", SqlDbType.Int, 4, task.PK_ID);
			cmd.Parameters.Add(result);

			cmd.Parameters.Add( SQLUtility.ParameterIn("@TaskName", SqlDbType.NVarChar, 500, task.TaskName));
			cmd.Parameters.Add(SQLUtility.ParameterIn("@ExecuteNext", SqlDbType.DateTime, 8, task.ExecuteNext));
			cmd.Parameters.Add(SQLUtility.ParameterIn("@Finished", SqlDbType.Bit, 1, task.Finished));
			cmd.Parameters.Add(SQLUtility.ParameterIn("@Frequency", SqlDbType.Int, 4, (int) task.Frequency));
			cmd.Parameters.Add(SQLUtility.ParameterIn("@Interval", SqlDbType.Int, 4, task.Interval));
			cmd.Parameters.Add(SQLUtility.ParameterIn("@TimesRemaining", SqlDbType.Int, 4, task.TimesRemaining));
			cmd.Parameters.Add(SQLUtility.ParameterIn("@Execute", SqlDbType.NVarChar, 500, task.Execute));
			cmd.Parameters.Add(SQLUtility.ParameterIn("@TaskExpires", SqlDbType.Bit, 1, task.TaskExpires));
			cmd.Parameters.Add(SQLUtility.ParameterIn("@ExpireTask", SqlDbType.DateTime, 8, task.ExpireTask));
			cmd.ExecuteNonQuery();
			ReleaseConnection();

			if (task.PK_ID == -1)
				task.PK_ID = (int)result.Value;

			return task.PK_ID;
		}
		/// <summary>
		/// Deletes a task by it's ID.
		/// </summary>
		/// <param name="PK_ID"></param>
		/// <returns></returns>
		public bool DeleteByID(int PK_ID)
		{
			if (PK_ID == -1) return false;
			EstablishConnection();

			SqlCommand cmd = this.CreateSqlCommand("coreSchedulerDeleteByID");
			cmd.Parameters.Add(SQLUtility.ParameterIn("@PK_ID", SqlDbType.Int, 4, PK_ID));
			cmd.ExecuteNonQuery();

			ReleaseConnection();
			return true;
		}
	}
}
